﻿using SketchUpAPI.NET.Enums;
using SketchUpAPI.NET.SketchUp.Exception;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace SketchUpAPI.NET.Objects
{
    /// <summary>
    /// 添加面的辅助类
    /// </summary>
    /// <remarks>对 SketchUpAPI 中的 SULoopInputRef 的包装</remarks>
    public class LoopInput : ObjectBase
    {
        #region API 函数
        /// <summary>
        /// 创建一个 LoopInput
        /// </summary>
        /// <param name="loopInputRef"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULoopInputCreate(out IntPtr loopInputRef);

        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param name="loop_input"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULoopInputRelease(ref IntPtr loop_input);

        /// <summary>
        /// 设置一个顶点序号
        /// </summary>
        /// <param name="loopInputRef"></param>
        /// <param name="index">顶点序号</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULoopInputAddVertexIndex(IntPtr loopInputRef, int index);

        /// <summary>
        /// 设置某个边是否隐藏
        /// </summary>
        /// <param name="loop_input"></param>
        /// <param name="edge_index">边缘序号</param>
        /// <param name="hidden">是否隐藏</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULoopInputEdgeSetHidden(IntPtr loop_input, long edge_index, bool hidden);

        /// <summary>
        /// 设置某个边是否软化
        /// </summary>
        /// <param name="loop_input">LoopInput</param>
        /// <param name="edge_index">要软化的边的序号</param>
        /// <param name="soft">是否软化</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULoopInputEdgeSetSoft(IntPtr loop_input, long edge_index, bool soft);

        /// <summary>
        /// 设置某个边是否柔滑
        /// </summary>
        /// <param name="loop_input">LoopInput</param>
        /// <param name="edge_index">要柔滑的边的序号</param>
        /// <param name="smooth">是否柔滑</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULoopInputEdgeSetSmooth(IntPtr loop_input, long edge_index, bool smooth);

        /// <summary>
        /// 为一个边设置材质
        /// </summary>
        /// <param name="loop_input"></param>
        /// <param name="edge_index">边缘序号</param>
        /// <param name="material"><see cref="Material"/> 材质</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULoopInputEdgeSetMaterial(IntPtr loop_input, long edge_index, IntPtr material);

        /// <summary>
        /// 为一个边设置图层
        /// </summary>
        /// <param name="loop_input"></param>
        /// <param name="edge_index">边的序号</param>
        /// <param name="layer"><see cref="Layer"/> 图层</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULoopInputEdgeSetLayer(IntPtr loop_input, long edge_index, IntPtr layer);

        /// <summary>
        /// 添加曲线
        /// </summary>
        /// <param name="loop_input"></param>
        /// <param name="first_edge_index">第一条边的序号</param>
        /// <param name="last_edge_index">最后一条边的序号</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULoopInputAddCurve(IntPtr loop_input, long first_edge_index, long last_edge_index);

        /// <summary>
        /// 是否闭合
        /// </summary>
        /// <param name="loop_input"></param>
        /// <param name="is_closed"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULoopInputIsClosed(IntPtr loop_input, out bool is_closed);
        #endregion

        /// <summary>
        /// 环是否闭合
        /// </summary>
        public bool IsClosed
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SULoopInputIsClosed(Id, out bool isClosed));
                return isClosed;
            }
        }

        /// <summary>
        /// 创建一个 环数据输入
        /// </summary>
        public LoopInput()
        {
            SketchUpExceptionHelper.ThrowSUResult(SULoopInputCreate(out Id));
        }

        /// <summary>
        /// 将某个点作为顶点
        /// </summary>
        /// <param name="index">顶点序号</param>
        /// <returns></returns>
        public void AddVertex(int index)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULoopInputAddVertexIndex(Id, index));
        }

        /// <summary>
        /// 添加连续的顶点
        /// </summary>
        /// <param name="start">起始顶点</param>
        /// <param name="count">顶点个数</param>
        public void AddVertex(int start, int count)
        {
            foreach (var item in Enumerable.Range(start, count))
            {
                AddVertex(item);
            }
        }

        /// <summary>
        /// 添加多个顶点
        /// </summary>
        /// <param name="indices"></param>
        public void AddVertex(params int[] indices)
        {
            foreach (var item in indices)
            {
                AddVertex(item);
            }
        }

        /// <summary>
        /// 将相邻的几条边缘组成曲线
        /// </summary>
        /// <param name="firstIndex">第一条边缘的索引</param>
        /// <param name="lastIndex">第二条边缘的索引</param>
        public void AddCurve(long firstIndex, long lastIndex)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULoopInputAddCurve(Id, firstIndex, lastIndex));
        }

        /// <summary>
        /// 设置某个边是否隐藏
        /// </summary>
        /// <param name="edgeIndex">边缘序号</param>
        /// <param name="isHidden">是否隐藏</param>
        public void SetEdgeHidden(long edgeIndex, bool isHidden)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULoopInputEdgeSetHidden(Id, edgeIndex, isHidden));
        }

        /// <summary>
        /// 设置某个边是否软化
        /// </summary>
        /// <param name="edgeIndex">边的索引</param>
        /// <param name="isSoft">是否软化</param>
        public void SetEdgeSoft(long edgeIndex, bool isSoft)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULoopInputEdgeSetSoft(Id, edgeIndex, isSoft));
        }

        /// <summary>
        /// 设置某个边是否柔滑
        /// </summary>
        /// <param name="edgeIndex">边的索引</param>
        /// <param name="isSmooth">是否柔滑</param>
        public void SetEdgeSmooth(long edgeIndex, bool isSmooth)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULoopInputEdgeSetSmooth(Id, edgeIndex, isSmooth));
        }

        /// <summary>
        /// 设置某个边的材质
        /// </summary>
        /// <param name="edgeIndex">边缘索引</param>
        /// <param name="material">材质</param>
        public void SetEdgeMaterial(long edgeIndex, Material material)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULoopInputEdgeSetMaterial(Id, edgeIndex, material.Id));
        }

        /// <summary>
        /// 设置某个边的图层
        /// </summary>
        /// <param name="edgeIndex"></param>
        /// <param name="layer"></param>
        public void SetEdgeLayer(long edgeIndex, Layer layer)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULoopInputEdgeSetLayer(Id, edgeIndex, layer.Id));
        }

        public override void Dispose()
        {
            SketchUpExceptionHelper.ThrowSUResult(SULoopInputRelease(ref Id));
        }
    }
}